package com.ruoyi.web.controller.system;

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.ruoyi.common.config.RuoYiConfig;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.data.NumberingFormat;
import com.deepoove.poi.data.NumberingRenderData;
import com.deepoove.poi.data.Numberings;
import com.deepoove.poi.data.Pictures;
import com.deepoove.poi.xwpf.NiceXWPFDocument;
import com.deepoove.poi.xwpf.NumFormat;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.framework.web.domain.server.Sys;
import com.ruoyi.system.domain.GxAssess;
import com.ruoyi.system.domain.GxTaskData;
import com.ruoyi.system.domain.MyObject;
import com.ruoyi.system.service.IGxAssessService;
import com.ruoyi.system.service.IGxWordTemplateService;
import com.ruoyi.system.service.ISysUserService;
import com.sun.jna.platform.win32.OaIdl;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.parameters.P;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.spring.web.json.Json;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.*;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.*;

import com.documents4j.api.DocumentType;
import com.documents4j.api.IConverter;
import com.documents4j.job.LocalConverter;

/**
 * GxWordTemplateController
 *
 * @author pqj
 * @date 2023-01-27
 */
@RestController
@RequestMapping("/system/word")
public class GxWordTemplateController extends BaseController {
    @Autowired
    private IGxWordTemplateService gxWordTemplateService;
    @Autowired
    private ISysUserService sysUserService;

    String signatureImgUrl = "";
    String phase = "";

    @GetMapping("/send")
    public void queryWordData(GxTaskData gxTaskData, HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 读取 properties 文件配置
        Properties properties = new Properties();
        Thread currentThread = Thread.currentThread();
        ClassLoader contextClassLoader = currentThread.getContextClassLoader();
        InputStream configStream = contextClassLoader.getResourceAsStream("wordPath.properties");
        if (configStream != null) {
            properties.load(configStream);

            //  TODO close the stream
        } else {
            // Properties file not found!
        }
        String componentPath = properties.getProperty("componentPath");// 组件存放路径
        String templatePath = properties.getProperty("templatePath");// 模板存放路径

        // 实例化 GxWordTemplateController，使用 trimStringWith() 函数 去掉 value首位的 双引号
        GxWordTemplateController trimDouble = new GxWordTemplateController();

        //1、获取到输出word文档所需的所有数据
        List<GxTaskData> list = gxWordTemplateService.selectGxTaskDataList(gxTaskData);

        // （0）CST时间处理
        Date date = DateUtil.parseCST(list.get(0).getAssessTime().toString());
        String assessTime = date.toString().substring(0, 10);

        SysUser userInfo = sysUserService.selectUserById(list.get(0).getMasterId());
        //（1）处理评定阶段phase
        if (list.get(0).getPhase().equals("1")) {
            phase = "初期";
        } else if (list.get(0).getPhase().equals("2")) {
            phase = "中期";
        } else {
            phase = "末期";
        }

        //（2）处理获取到的签名图片地址
        signatureImgUrl = userInfo.getSignature();
        signatureImgUrl = signatureImgUrl.replace("/", "\\");

        String profilePath = RuoYiConfig.getProfile();
        profilePath.replace("/", "\\");
        signatureImgUrl = signatureImgUrl.replace("\\profile", profilePath);


        //2、解析JSON字符串
        String jsonAssessConfig = list.get(0).getAssessConfig();
        ObjectMapper mapper = new ObjectMapper();
        List<MyObject> javaAssessConfig = mapper.readValue(jsonAssessConfig, new TypeReference<List<MyObject>>() {
        });

        //3、将每个容器名生成对应的word文档 并 插入{{containerName1、2、3.....}}文本标签
        for (int i = 0; i < javaAssessConfig.size(); i++) {
            //（1）在E:\poi-test\ 目录下 生成一个 以 containerName 为 文件名 的 .docx 文件
            String containerName = "containerName" + (i + 1);
            XWPFDocument doc = new XWPFDocument();
            try (FileOutputStream out = new FileOutputStream(componentPath + containerName + ".docx")) {
                doc.write(out);
            }
            //（2）创建段落和run对象，将 {{containerName}} 文本标签 插入到 此 .docx 文件中
            XWPFParagraph paragraph = doc.createParagraph();
            XWPFRun run = paragraph.insertNewRun(0);
            run.setText("{{containerName" + (i + 1) + "}}");
            run.setBold(true);
            run.setFontFamily("宋体");
            run.setFontSize(16);
            FileOutputStream out = new FileOutputStream(componentPath + containerName + ".docx");
            doc.write(out);
            doc.close();
            out.close();
        }


        //4、遍历 评定表配置assessConfig 找到对应组件的word文档，然后依次合并到 固定模板 template 中
        NiceXWPFDocument template = new NiceXWPFDocument(new FileInputStream(templatePath + "template.docx"));
        for (int i = 0; i < javaAssessConfig.size(); i++) {
            //（1）先合并容器名对应的word文档
            NiceXWPFDocument containerName = new NiceXWPFDocument(new FileInputStream(componentPath + "containerName" + (i + 1) + ".docx"));
            template = template.merge(containerName);
            //（2）在合并当前容器下的组件对应的word文档
            List<String> assConfig = javaAssessConfig.get(i).getAssConfig();
            for (int j = 0; j < assConfig.size(); j++) {
                NiceXWPFDocument component = new NiceXWPFDocument(new FileInputStream(componentPath + assConfig.get(j) + ".docx"));
                template = template.merge(component);
            }
        }
        //5、将签名模板合并到 template 模板中
        NiceXWPFDocument signatureImgDoc = new NiceXWPFDocument(new FileInputStream(componentPath + "signature.docx"));
        template = template.merge(signatureImgDoc);
        //6、将合并好的 template 模板 保存到当前目录 （到这里生成 output.docx 文件）
        FileOutputStream mergeOut = new FileOutputStream(componentPath + "output.docx");

        template.write(mergeOut);
        template.close();
        mergeOut.close();


        Map<String, Object> jsonMap = new HashMap<>();
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            jsonMap = mapper.readValue(list.get(0).getAssessData(), Map.class);
        } catch (IOException e) {
            // TODO handle exception properly
        }
        ArrayList<String> keys = new ArrayList<String>();
        for (Map.Entry<String, Object> entry : jsonMap.entrySet()) {
            System.out.println(entry.getKey() + ":" + entry.getValue());
            keys.add(entry.getKey());
            Map<String, Object> subMap = new HashMap<>();
            try {
                subMap = mapper.readValue(entry.getKey(), Map.class);
            } catch (IOException e) {
                // TODO handle exception properly
            }
            for (Map.Entry<String, Object> entry1 : subMap.entrySet()) {
                System.out.println("------------------------------------------------");
                System.out.println(entry1.getKey() + ":" + entry1.getValue());
                System.out.println("------------------------------------------------");
            }
        }


        //6、渲染合并后的模板
        String finalSignatureImgUrl = signatureImgUrl;
        XWPFTemplate temp = XWPFTemplate.compile(componentPath + "output.docx").render(
                new HashMap<String, Object>() {{
                    //（1）渲染：表头固定结构
                    put("assessName", list.get(0).getAssessName());
                    put("containerName", "一、基本情况");
                    put("name", list.get(0).getPatientName());
                    put("sex", list.get(0).getPatientGender() == "0" ? "女" : "男");
                    put("age", list.get(0).getPatientAge());
                    put("identityNo", list.get(0).getPatientIdentityNo());
                    put("abstract", list.get(0).getIllnessSummary());
                    put("history", list.get(0).getPreHistory());
                    put("diagnose", list.get(0).getPreDiagnose());
                    put("assessDate", assessTime);
                    put("assesser", list.get(0).getDoctorName());
                    put("phase", phase);
                    put("auditer", list.get(0).getMasterName());
                    put("signature", Pictures.ofLocal(signatureImgUrl).size(200, 100).create());

                    //（2）渲染：容器名
                    for (int i = 0; i < javaAssessConfig.size(); i++) {
                        put("containerName" + (i + 1), javaAssessConfig.get(i).getTitleName());
                    }

                    //（3）渲染：容器内组件的值
                    Map<String, Object> data = new LinkedHashMap<>();
                    ObjectMapper objectMapper = new ObjectMapper();
                    JsonNode assessData = objectMapper.readTree(list.get(0).getAssessData());
                    String value = "";
                    if (assessData.isContainerNode()) {
                        Iterator<String> keys = assessData.fieldNames();
                        while (keys.hasNext()) {
                            String key = keys.next();
                            String str = assessData.get(key).toString();
                            JsonNode jn = objectMapper.readTree(str);
                            if (jn.isContainerNode()) {
                                Iterator<String> sub = jn.fieldNames();
                                while (sub.hasNext()) {
                                    String key1 = sub.next();
//                                    value = trimDouble.trimStringWith(jn.get(key1).toString(), '"');

                                    // 如果节点是数组，则遍历其中的元素
                                    if (jn.get(key1).isArray()) {
                                        ArrayNode arrayNode = (ArrayNode) jn.get(key1);
                                        List<Object> list = new ArrayList<>();
                                        for (JsonNode element : arrayNode) {
                                            if (element.isTextual()) {
                                                // 如果元素是字符串，则去掉首尾双引号
                                                String ele = element.asText();
                                                // String ele = element.asText().replaceAll("^\"|\"$", "");
                                                list.add(ele);
                                            } else {
                                                // 如果元素不是字符串，则直接添加到列表中
                                                list.add(element);
                                            }
                                        }
                                        data.put(key1, list);
                                    } else {
                                        data.put(key1, jn.get(key1).asText());
                                    }
                                }
                            }
                        }
                    }
                    for (Map.Entry<String, Object> entry : data.entrySet()) {
                        put(entry.getKey(), entry.getValue());
                    }
                    ;
                }});
        //（4）渲染完毕，将最终文档输出


//        temp.writeAndClose(new FileOutputStream(componentPath + "final.docx"));
//        response.setContentType("application/pdf");
//        response.setHeader("Content-Disposition", "attachment; filename=\"finalpdf.pdf\"");
        response.setHeader("Content-Disposition", "attachment; filename=" + list.get(0).getAssessName() + ".docx");
        response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=UTF-8");
        OutputStream outputStream = response.getOutputStream();
        temp.write(outputStream);
        outputStream.close();
        temp.close();


//        word2pdf(response);

//        creatOutPusStream(response, temp);

        /*try {
            //禁用缓存
            String name = "final";
            response.setHeader(HttpHeaders.PRAGMA, "No-cache");
            response.setHeader(HttpHeaders.CACHE_CONTROL, "No-cache");
            response.setHeader("Content-Disposition", "attachment; filename="+name+".docx");
            response.setHeader(HttpHeaders.CONTENT_TYPE, "application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=UTF-8");
            //response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=UTF-8");
            OutputStream outputStream = response.getOutputStream();
            temp.write(outputStream);
            outputStream.close();
            temp.close();
        }catch (Exception e){
            e.printStackTrace();
        }*/

        /*response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
        response.setHeader("Content-disposition", "attachment;filename=output.docx");

        try {
            temp.write(response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }*/


        //7、word转pdf
        /*InputStream in = new FileInputStream(new File("E:\\poi-test\\final.docx"));
        XWPFDocument document = new XWPFDocument(in);

        File outFile = new File("E:\\poi-test\\final.pdf");
        OutputStream out = new FileOutputStream(outFile);
        PdfOptions options = PdfOptions.create();
        PdfConverter.getInstance().convert(document, out, options);
        in.close();
        out.close();*/

//        return getDataTable(list);
    }

    @GetMapping("/sendPdf")
    public void queryPdfData(GxTaskData gxTaskData, HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 读取 properties 文件配置
        Properties properties = new Properties();
        Thread currentThread = Thread.currentThread();
        ClassLoader contextClassLoader = currentThread.getContextClassLoader();
        InputStream configStream = contextClassLoader.getResourceAsStream("wordPath.properties");
        if (configStream != null) {
            properties.load(configStream);

            //  TODO close the stream
        } else {
            // Properties file not found!
        }
        String componentPath = properties.getProperty("componentPath");
        String templatePath = properties.getProperty("templatePath");

        // 实例化 GxWordTemplateController，使用 trimStringWith() 函数 去掉 value首位的 双引号
        GxWordTemplateController trimDouble = new GxWordTemplateController();

        //1、获取到输出word文档所需的所有数据
        List<GxTaskData> list = gxWordTemplateService.selectGxTaskDataList(gxTaskData);
        // （0）CST时间处理
        Date date = DateUtil.parseCST(list.get(0).getAssessTime().toString());
        String assessTime = date.toString().substring(0, 10);

        SysUser userInfo = sysUserService.selectUserById(list.get(0).getMasterId());
        //（1）处理评定阶段phase
        if (list.get(0).getPhase().equals("1")) {
            phase = "初期";
        } else if (list.get(0).getPhase().equals("2")) {
            phase = "中期";
        } else {
            phase = "末期";
        }

        //（2）处理获取到的签名图片地址
        signatureImgUrl = userInfo.getSignature();
        signatureImgUrl = signatureImgUrl.replace("/", "\\");

        String profilePath = RuoYiConfig.getProfile();
        profilePath.replace("/", "\\");
        signatureImgUrl = signatureImgUrl.replace("\\profile", profilePath);


        //2、解析JSON字符串
        String jsonAssessConfig = list.get(0).getAssessConfig();
        ObjectMapper mapper = new ObjectMapper();
        List<MyObject> javaAssessConfig = mapper.readValue(jsonAssessConfig, new TypeReference<List<MyObject>>() {
        });

        //3、将每个容器名生成对应的word文档 并 插入{{containerName1、2、3.....}}文本标签
        for (int i = 0; i < javaAssessConfig.size(); i++) {
            //（1）在E:\poi-test\ 目录下 生成一个 以 containerName 为 文件名 的 .docx 文件
            String containerName = "containerName" + (i + 1);
            XWPFDocument doc = new XWPFDocument();
            try (FileOutputStream out = new FileOutputStream(componentPath + containerName + ".docx")) {
                doc.write(out);
            }
            //（2）创建段落和run对象，将 {{containerName}} 文本标签 插入到 此 .docx 文件中
            XWPFParagraph paragraph = doc.createParagraph();
            XWPFRun run = paragraph.insertNewRun(0);
            run.setText("{{containerName" + (i + 1) + "}}");
            run.setBold(true);
            run.setFontSize(16);
            FileOutputStream out = new FileOutputStream(componentPath + containerName + ".docx");
            doc.write(out);
            doc.close();
            out.close();
        }


        //4、遍历 评定表配置assessConfig 找到对应组件的word文档，然后依次合并到 固定模板 template 中
        NiceXWPFDocument template = new NiceXWPFDocument(new FileInputStream(templatePath + "template.docx"));
        for (int i = 0; i < javaAssessConfig.size(); i++) {
            //（1）先合并容器名对应的word文档
            NiceXWPFDocument containerName = new NiceXWPFDocument(new FileInputStream(componentPath + "containerName" + (i + 1) + ".docx"));
            template = template.merge(containerName);
            //（2）在合并当前容器下的组件对应的word文档
            List<String> assConfig = javaAssessConfig.get(i).getAssConfig();
            for (int j = 0; j < assConfig.size(); j++) {
                NiceXWPFDocument component = new NiceXWPFDocument(new FileInputStream(componentPath + assConfig.get(j) + ".docx"));
                template = template.merge(component);
            }
        }
        //5、将签名模板合并到 template 模板中
        NiceXWPFDocument signatureImgDoc = new NiceXWPFDocument(new FileInputStream(componentPath + "signature.docx"));
        template = template.merge(signatureImgDoc);
        //6、将合并好的 template 模板 保存到当前目录 （到这里生成 output.docx 文件）
        FileOutputStream mergeOut = new FileOutputStream(componentPath + "output.docx");

        template.write(mergeOut);
        template.close();
        mergeOut.close();


        Map<String, Object> jsonMap = new HashMap<>();
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            jsonMap = mapper.readValue(list.get(0).getAssessData(), Map.class);
        } catch (IOException e) {
            // TODO handle exception properly
        }
        ArrayList<String> keys = new ArrayList<String>();
        for (Map.Entry<String, Object> entry : jsonMap.entrySet()) {
            System.out.println(entry.getKey() + ":" + entry.getValue());
            keys.add(entry.getKey());
            Map<String, Object> subMap = new HashMap<>();
            try {
                subMap = mapper.readValue(entry.getKey(), Map.class);
            } catch (IOException e) {
                // TODO handle exception properly
            }
            for (Map.Entry<String, Object> entry1 : subMap.entrySet()) {
                System.out.println("------------------------------------------------");
                System.out.println(entry1.getKey() + ":" + entry1.getValue());
                System.out.println("------------------------------------------------");
            }
        }


        //6、渲染合并后的模板
        String finalSignatureImgUrl = signatureImgUrl;
        System.out.println("-------------------------------------------------------");
        System.out.println(finalSignatureImgUrl);
        XWPFTemplate temp = XWPFTemplate.compile(componentPath + "output.docx").render(
                new HashMap<String, Object>() {{
                    //（1）渲染：表头固定结构
                    put("assessName", list.get(0).getAssessName());
                    put("containerName", "一、基本情况");
                    put("name", list.get(0).getPatientName());
                    put("sex", list.get(0).getPatientGender() == "0" ? "女" : "男");
                    put("age", list.get(0).getPatientAge());
                    put("identityNo", list.get(0).getPatientIdentityNo());
                    put("abstract", list.get(0).getIllnessSummary());
                    put("history", list.get(0).getPreHistory());
                    put("diagnose", list.get(0).getPreDiagnose());
                    put("assessDate", assessTime);
                    put("assesser", list.get(0).getDoctorName());
                    put("phase", phase);
                    put("auditer", list.get(0).getMasterName());
                    put("signature", Pictures.ofLocal(signatureImgUrl).size(200, 100).create());

                    //（2）渲染：容器名
                    for (int i = 0; i < javaAssessConfig.size(); i++) {
                        put("containerName" + (i + 1), javaAssessConfig.get(i).getTitleName());
                    }

                    //（3）渲染：容器内组件的值
                    Map<String, Object> data = new LinkedHashMap<>();
                    ObjectMapper objectMapper = new ObjectMapper();
                    JsonNode assessData = objectMapper.readTree(list.get(0).getAssessData());

                    if (assessData.isContainerNode()) {
                        Iterator<String> keys = assessData.fieldNames();
                        while (keys.hasNext()) {
                            String key = keys.next();
                            String str = assessData.get(key).toString();
                            JsonNode jn = objectMapper.readTree(str);
                            if (jn.isContainerNode()) {
                                Iterator<String> sub = jn.fieldNames();
                                while (sub.hasNext()) {
                                    String key1 = sub.next();
                                    // 如果节点是数组，则遍历其中的元素
                                    if (jn.get(key1).isArray()) {
                                        ArrayNode arrayNode = (ArrayNode) jn.get(key1);
                                        List<Object> list = new ArrayList<>();
                                        for (JsonNode element : arrayNode) {
                                            if (element.isTextual()) {
                                                // 如果元素是字符串，则去掉首尾双引号
                                                String ele = element.asText();
                                                list.add(ele);
                                            } else {
                                                // 如果元素不是字符串，则直接添加到列表中
                                                list.add(element);
                                            }
                                        }
                                        data.put(key1, list);
                                    } else {
                                        data.put(key1, jn.get(key1).asText());
                                    }
                                }
                            }
                        }
                    }
                    for (Map.Entry<String, Object> entry : data.entrySet()) {
                        put(entry.getKey(), entry.getValue());
                    }
                    ;
                }});
        //（4）渲染完毕，将最终文档输出
        temp.writeAndClose(new FileOutputStream(componentPath + "final.docx"));
        response.setContentType("application/pdf");
        response.setHeader("Content-Disposition", "attachment; filename=\"finalpdf.pdf\"");
        word2pdf(response, false);
    }

    @GetMapping("/sendJump")
    public void queryWordJumpData(GxTaskData gxTaskData, HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 读取 properties 文件配置
        Properties properties = new Properties();
        Thread currentThread = Thread.currentThread();
        ClassLoader contextClassLoader = currentThread.getContextClassLoader();
        InputStream configStream = contextClassLoader.getResourceAsStream("wordPath.properties");
        if (configStream != null) {
            properties.load(configStream);

            //  TODO close the stream
        } else {
            // Properties file not found!
        }
        String jumpTablePath = properties.getProperty("jumpTablePath");

        //1、获取到输出word文档所需的所有数据
        List<GxTaskData> list = gxWordTemplateService.selectGxTaskDataList(gxTaskData);
        String jumpTableName = gxTaskData.getJumpTableName();
        String json = list.get(0).getAssessData();

        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode jsonNode = objectMapper.readTree(json);

        XWPFTemplate template = XWPFTemplate.compile(jumpTablePath + jumpTableName + ".docx").render(
                new HashMap<String, Object>() {{
                    jsonNode.fields().forEachRemaining(entry -> {
                        String key = entry.getKey(); //barthel
                        String jump = jumpTableName.substring(0, jumpTableName.length() - 4); // 截取掉最后四位的 Jump，"barthelJump" --> "barthel"
                        System.out.println("key: " + key);
                        System.out.println("jump: " + jump);
                        if (key.equals(jump)) {
                            JsonNode value = entry.getValue();
                            if (value.isContainerNode()) {
                                value.fields().forEachRemaining(item -> {
                                    String childKey = item.getKey();
                                    JsonNode childValue = item.getValue();
                                    System.out.println("----------------------------------");
                                    System.out.println("childKey：" + childKey);
                                    System.out.println("childValue：" + childValue);
//                                    put(childKey, GxWordTemplateController.removeSingleQuotesFromStartAndEnd(childValue.asText()));

                                    // 如果节点是数组，则遍历其中的元素  jn.get(key1) 这个就是 childValue
                                    if (childValue.isArray()) {
                                        ArrayNode arrayNode = (ArrayNode) childValue;
                                        List<Object> list = new ArrayList<>();
                                        for (JsonNode element : arrayNode) {
                                            if (element.isTextual()) {
                                                // 如果元素是字符串，则去掉首尾双引号
                                                System.out.println("element:" + element);
                                                String ele = element.asText();
                                                System.out.println("ele:" + ele);
                                                // String ele = element.asText().replaceAll("^\"|\"$", "");
                                                list.add(ele);
                                            } else {
                                                // 如果元素不是字符串，则直接添加到列表中
                                                list.add(element);
                                            }
                                        }
                                        put(childKey, list);
                                    } else {
                                        put(childKey, childValue.asText());
                                    }
                                });
                            }
                        }
                    });
                }}
        );
//        template.writeAndClose(new FileOutputStream(jumpTablePath + "final.docx"));

        response.setHeader("Content-Disposition", "attachment; filename=" + jumpTablePath + ".docx");
        response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=UTF-8");
        OutputStream outputStream = response.getOutputStream();
        template.write(outputStream);
        outputStream.close();
        template.close();
    }

    @GetMapping("/sendPdfJump")
    public void queryPdfJumpData(GxTaskData gxTaskData, HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 读取 properties 文件配置
        Properties properties = new Properties();
        Thread currentThread = Thread.currentThread();
        ClassLoader contextClassLoader = currentThread.getContextClassLoader();
        InputStream configStream = contextClassLoader.getResourceAsStream("wordPath.properties");
        if (configStream != null) {
            properties.load(configStream);

            //  TODO close the stream
        } else {
            // Properties file not found!
        }
        String jumpTablePath = properties.getProperty("jumpTablePath");

        //1、获取到输出word文档所需的所有数据
        List<GxTaskData> list = gxWordTemplateService.selectGxTaskDataList(gxTaskData);
        String jumpTableName = gxTaskData.getJumpTableName();
        String json = list.get(0).getAssessData();

        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode jsonNode = objectMapper.readTree(json);

        XWPFTemplate template = XWPFTemplate.compile(jumpTablePath + jumpTableName + ".docx").render(
                new HashMap<String, Object>() {{
                    jsonNode.fields().forEachRemaining(entry -> {
                        String key = entry.getKey(); //barthel
                        String jump = jumpTableName.substring(0, jumpTableName.length() - 4); // 截取掉最后四位的 Jump，"barthelJump" --> "barthel"
                        System.out.println("key: " + key);
                        System.out.println("jump: " + jump);
                        if (key.equals(jump)) {
                            JsonNode value = entry.getValue();
                            if (value.isContainerNode()) {
                                value.fields().forEachRemaining(item -> {
                                    String childKey = item.getKey();
                                    JsonNode childValue = item.getValue();
                                    put(childKey, GxWordTemplateController.removeSingleQuotesFromStartAndEnd(childValue.asText()));
                                });
                            }
                        }
                    });
                }}
        );
        template.writeAndClose(new FileOutputStream(jumpTablePath + "final.docx"));
        response.setContentType("application/pdf");
        response.setHeader("Content-Disposition", "attachment; filename=\"finalpdf.pdf\"");
        word2pdf(response, true);
    }

    /**
     * 写入响应流
     *
     * @param response
     * @param template
     */
    public void creatOutPusStream(HttpServletResponse response, XWPFTemplate template) {
        //=================生成文件保存在临时目录=================
        String temDir = System.getProperty("java.io.tmpdir") + File.separator;//生成临时文件存放地址
        //生成文件名
        Long time = new Date().getTime();
        // 生成的word格式
        String formatSuffix = ".docx";
        // 拼接后的文件名
        String fileName = time + formatSuffix;//文件名  带后缀
        //文件路径
        String filePath = temDir + fileName;

        FileOutputStream fos = null;
        OutputStream out = null;
        try {
            fos = new FileOutputStream(filePath);
            template.write(fos);
            //=================生成word到设置浏览默认下载地址=================
            response.setCharacterEncoding("UTF-8");
            //设置文件格式
            response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
            // 设置文件名
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(("清单列表").getBytes("GBK"), "ISO8859-1") + ".docx");
            out = response.getOutputStream();
            template.write(out);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.flush();
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (template != null) {
                try {
                    template.close();
                } catch (IOException e) {
                }
            }
            File file = new File(filePath);
            if (file.exists()) {
                file.delete();
            }
        }

    }


    public String trimStringWith(String str, char beTrim) {
        int st = 0;
        int len = str.length();
        char[] val = str.toCharArray();
        char sbeTrim = beTrim;
        while ((st < len) && (val[st] <= sbeTrim)) {
            st++;
        }
        while ((st < len) && (val[len - 1] <= sbeTrim)) {
            len--;
        }
        return ((st > 0) || (len < str.length())) ? str.substring(st, len) : str;
    }

    // word转pdf工具函数
    public void word2pdf(HttpServletResponse response, Boolean type) throws IOException {
        // 读取 properties 文件配置
        Properties properties = new Properties();
        Thread currentThread = Thread.currentThread();
        ClassLoader contextClassLoader = currentThread.getContextClassLoader();
        InputStream configStream = contextClassLoader.getResourceAsStream("wordPath.properties");
        if (configStream != null) {
            properties.load(configStream);

            //  TODO close the stream
        } else {
            // Properties file not found!
        }
        String jumpTablePath = properties.getProperty("jumpTablePath");
        String poiTestPath = properties.getProperty("componentPath");
        InputStream docxInputStream = null;
        OutputStream outputStream = null;
        try {
            // 原word地址
            if (type) {
                docxInputStream = new FileInputStream( jumpTablePath + "final.docx");

            } else {
                docxInputStream = new FileInputStream( poiTestPath + "final.docx");
            }

            // 转换后pdf生成地址
            outputStream = response.getOutputStream();
            IConverter converter = LocalConverter.builder().build();
            converter.convert(docxInputStream)
                    .as(DocumentType.DOCX)
                    .to(outputStream)
                    .as(DocumentType.PDF).execute();
            // 关闭
            converter.shutDown();
            // 关闭
            outputStream.flush();
        } catch (Exception e) {
            response.getWriter().println("[documents4J] word转pdf失败:" + e.toString());
        } finally {
            if (docxInputStream != null) {
                docxInputStream.close();
            }
        }
    }
    // 判断一个字符串首位是否有单引号'，如果有则删除
    public static String removeSingleQuotesFromStartAndEnd(String input) {
        if (input == null || input.isEmpty()) {
            return input; // Return the input unchanged if it's null or empty
        }

        // Check if the string starts and ends with a single quote
        if (input.startsWith("'") && input.endsWith("'")) {
            // If yes, remove the first and last characters (single quotes)
            return input.substring(1, input.length() - 1);
        }

        return input; // Return the input unchanged if it doesn't start and end with single quotes
    }
}

